package org.budo.mybatis.dao.statement.builder.creator;

import org.apache.ibatis.session.Configuration;
import org.budo.mybatis.dao.statement.builder.impl.DefaultStatementBuilder;
import org.budo.mybatis.dao.statement.builder.util.StatementBuilderUtil;

/**
 * @author lmw
 */
public abstract class AbstractStatementCreator implements StatementCreator {
    private Configuration configuration;

    private DefaultStatementBuilder statementBuilder;

    public AbstractStatementCreator(Configuration configuration, DefaultStatementBuilder statementBuilder) {
        this.configuration = configuration;
        this.statementBuilder = statementBuilder;
    }

    public Configuration getConfiguration() {
        return configuration;
    }

    public DefaultStatementBuilder getStatementBuilder() {
        return statementBuilder;
    }

    public void buildStatement(Class<?> entityType) {
        String statement = entityType.getName() + this.getStatementId();

        // 初次检查
        if (configuration.hasStatement(statement, false)) {
            return;
        }

        synchronized (AbstractStatementCreator.class) {
            if (configuration.hasStatement(statement, false)) { // 加锁后检查
                return;
            }

            // 初次检查未完成的 Statement
            if (configuration.hasStatement(statement, true)) {
                return;
            }

            synchronized (AbstractStatementCreator.class) {
                if (configuration.hasStatement(statement, true)) { // 加锁检查未完成的 Statement
                    return;
                }

                String statementXml = this.createStatement(entityType);
                StatementBuilderUtil.parseXmlMapper(configuration, entityType.getName(), statementXml);
            }
        }
    }

    protected abstract String getStatementId();

    protected abstract String createStatement(Class<?> entityType);
}
